﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace DevTools.HardDiskVisualizer.Components
{
    public class FolderList : IEnumerable<Folder>
    {
        #region singleton
        private static FolderList _instance;

        public static FolderList Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new FolderList();
                return _instance;
            }
        }

        private FolderList()
        {
        }
        #endregion

        private readonly List<Folder> _innerList = new List<Folder>();

        public void Scan(string path)
        {
            Folder folder = new Folder(path);
            ScanCore(folder);
        }

        public void ScanCore(Folder folder)
        {
            OnScanBeginning(folder);

            _innerList.Add(folder);

            DirectoryInfo directory = new DirectoryInfo(folder.Path);

            try
            {
                var files = directory.GetFiles();
                folder.Size = files.Sum(x => x.Length);
            }
            catch
            {
            }

            try
            {
                var directories = directory.GetDirectories();
                folder.AddChildren(directories);
            }
            catch
            {
            }

            foreach (var child in folder)
                ScanCore(child);
        }

        public void CalculateSum()
        {
            while (Folder.DeepestDepth != -1)
            {
                var folders = _innerList.FindAll(x => x.Depth == Folder.DeepestDepth);
                folders.ForEach(x => x.CalculateSum());

                Folder.DeepestDepth--;
            }
        }

        public IEnumerator<Folder> GetEnumerator()
        {
            foreach (var folder in _innerList)
                yield return folder;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #region ScanBeginning event things for C# 3.0
        public event EventHandler<ScanBeginningEventArgs> ScanBeginning;

        protected virtual void OnScanBeginning(ScanBeginningEventArgs e)
        {
            if (ScanBeginning != null)
                ScanBeginning(this, e);
        }

        protected virtual void OnScanBeginning(Folder folder)
        {
            if (ScanBeginning != null)
                ScanBeginning(this, new ScanBeginningEventArgs(folder));
        }

        public class ScanBeginningEventArgs : EventArgs
        {
            public Folder Folder { get; set; }

            public ScanBeginningEventArgs()
            {
            }

            public ScanBeginningEventArgs(Folder folder)
            {
                Folder = folder;
            }
        }
        #endregion
    }
}
